/*
 *  WandererAI.cpp
 *  RiskAI
 *
 *  Created by Chris on 11/15/09.
 *  Copyright 2009 __MyCompanyName__. All rights reserved.
 *
 */

#include "WandererAI.h"

#include <vector>
#include <iostream>

using namespace std;

//**********************************************************************************
//				CONSTRUCTION/DESTRUCTION
//**********************************************************************************

CWandererAI::CWandererAI(int iIndex, CBoard* pxBoard)
	: CPlayer(iIndex, pxBoard)
	, m_iHorde(-1)
	, m_iTarget(-1)
{
}





//**********************************************************************************
//				HELPER FUNCTIONS
//**********************************************************************************

void
CWandererAI::PickHorde()
{
	int iMaxTroops = 0;
	
	for(unsigned int i=0; i<m_viTerritories.size(); i++)
	{
		int iTroops = m_pxBoard->GetTerritory(m_viTerritories[i])->GetNumArmies();
		int iEnemies = m_pxBoard->EnemiesSurroundingTerritory(m_viTerritories[i]);
		if(iTroops > iMaxTroops && iEnemies > 0) iMaxTroops = iTroops;
	}
	
	int iLeastEnemies = INFINITY;
	int iBestChoice;
	
	for(unsigned int i=0; i<m_viTerritories.size(); i++)
	{
		int iTroops = m_pxBoard->GetTerritory(m_viTerritories[i])->GetNumArmies();
		if(iTroops == iMaxTroops)
		{
			int iEnemies = StrengthOfWeaskestEnemy(m_viTerritories[i]);
			if(iEnemies < iLeastEnemies)
			{
				iLeastEnemies = iEnemies;
				iBestChoice = m_viTerritories[i];
			}
		}
	}
	
	m_iHorde = iBestChoice;
}






//**********************************************************************************
//				VIRTUAL FUNCTIONS
//**********************************************************************************

int
CWandererAI::PickTerritory(vector<int> viAvailables)
{
	return rand() % viAvailables.size();
}

//==================================================================================

int
CWandererAI::AssignTroops(int iNumTroops)
{
	/*
	 *	If I haven't figured out yet which is the best territory, figure it out.
	 */
	
	if(m_iHorde == -1)
		PickHorde();
	
	m_iTarget = -1;
	return m_iHorde;
}

//==================================================================================

int
CWandererAI::MoveTroops(int iSourceIndex, int iDestinationIndex)
{
	return m_pxBoard->GetTerritory(iSourceIndex)->GetNumArmies() - 1;
}

//==================================================================================

RiskAction
CWandererAI::DecideOnAction(vector<int> viViableAttackers)
{	
	if(m_pxBoard->GetTerritory(m_iHorde)->GetNumArmies() > 1)
	{
		if(m_iTarget == -1)
		{
			vector<int> viTargets = m_pxBoard->GetTerritory(m_iHorde)->GetBorderIndices();
			int iWeakestForce = INFINITY;
			int iWeakestTarget = -1;
			
			for(unsigned int i=0; i<viTargets.size(); i++)
			{
				int iIndex = viTargets[i];
				int iOwner = m_pxBoard->GetTerritory(iIndex)->GetOwner();
				int iEnemies = m_pxBoard->GetTerritory(iIndex)->GetNumArmies();
				if(m_iIndex != iOwner && iEnemies < iWeakestForce)
				{
					iWeakestForce = iEnemies;
					iWeakestTarget = iIndex;
				}
			}
			
			m_iTarget = iWeakestTarget;
		}
		
		if(m_iTarget == -1) return END_TURN;
		
		int iDice = min(m_pxBoard->GetTerritory(m_iHorde)->GetNumArmies() - 1, 3);
		
		return RiskAction(m_iHorde, m_iTarget, iDice);		
	}
	
	return END_TURN;
}

//==================================================================================

int
CWandererAI::PickDefendingDie(int* aiAttackDice, int iTarget)
{
	int iMaxDice = min(m_pxBoard->GetTerritory(iTarget)->GetNumArmies(), 2);
	
	return (aiAttackDice[1] > 3 ? 1 : iMaxDice);
}

//==================================================================================

CFortification
CWandererAI::FortifyTroops(vector<int> viFortifiers)
{
	/*
	 *	Check if my attack was successful.
	 */
	 
	if(m_iTarget != -1 && m_iIndex == m_pxBoard->GetTerritory(m_iTarget)->GetOwner())
		m_iHorde = m_iTarget;
	
	
	
	
	/*
	 *	Check if I need to move the horde.
	 */
	
	if(m_pxBoard->EnemiesSurroundingTerritory(m_iHorde) == 0)
	{
		
		vector<int> viHordeBorders = m_pxBoard->GetTerritory(m_iHorde)->GetBorderIndices();
		viHordeBorders.push_back(m_iHorde);
		int iWeakestForce = INFINITY;
		int iWeakestTarget = -1;
		
		for(unsigned int i=0; i<viHordeBorders.size(); i++)
		{
			if(m_pxBoard->GetTerritory(viHordeBorders[i])->GetOwner() == m_iIndex)
			{
				int iEnemies = m_pxBoard->EnemiesSurroundingTerritory(viHordeBorders[i]);
				if(iEnemies != 0 && iEnemies < iWeakestForce)
				{
					iWeakestForce = iEnemies;
					iWeakestTarget = viHordeBorders[i];
				}
			}
		}
		
		
		
		/*
		 *	Move next to weakest territory.
		 */
		if(iWeakestTarget != -1 && iWeakestTarget != m_iHorde)
		{
			int iTroops = m_pxBoard->GetTerritory(m_iHorde)->GetNumArmies() - 1;
			CFortification xFort(m_iHorde, iWeakestTarget, iTroops);
			m_iHorde = -1;
			return xFort;
		}
		
		
		
		/*
		 *	If I'm out in the middle of nowhere, well that just sucks.
		 */
		m_iHorde = -1;
		return NO_FORTIFICATION;
	}
	
	
	
	/*
	 *	Check if any horde neighbors have surplus troops they can move.
	 */
	
	vector<int> viHordeBorders = m_pxBoard->GetTerritory(m_iHorde)->GetBorderIndices();
	int iMostTroops = 0;
	int iBestChoice = -1;
	
	for(unsigned int i=0; i<viHordeBorders.size(); i++)
	{
		int iIndex = viHordeBorders[i];
		int iOwner = m_pxBoard->GetTerritory(iIndex)->GetOwner();
		int iTroops = m_pxBoard->GetTerritory(iIndex)->GetNumArmies() - 1;
		if(m_iIndex == iOwner && iMostTroops < iTroops)
		{
			iMostTroops = iTroops;
			iBestChoice = iIndex;
		}
	}
	
	if(iBestChoice != -1)
	{
		CFortification xFort(iBestChoice, m_iHorde, iMostTroops);
		m_iHorde = -1;
		return xFort;
	}
	
	
	
	/*
	 *	Other than that, nothing to do.
	 */
	m_iHorde = -1;
	return NO_FORTIFICATION;
}